home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / YICN23.ZIP / DOC / YICONS.DOC < prev    next >
Text File  |  1993-03-06  |  34KB  |  941 lines

  1. Documentation file for YakIcons version 2.0
  2. ----------------------------------------------------------------------
  3.  
  4. YakIcons is a free shareware graphics library encompassing many aspects
  5. of game design and mechanics.  It is a series of object-oriented modules
  6. for Borland C++ version 3.1 and covers mouse and joystick support, sampled
  7. sound, fast icon drawing, restorable screen areas, editable fonts, tiled
  8. maps, etc, etc.
  9.  
  10. All units are compiled in the large memory model; I have no idea what will
  11. happen if you use others.
  12.  
  13. Thanks and other dedications:
  14.  
  15. J. Slagel-- his xblt code was my first inspiration.
  16. Themie Gouthas-- his xlib04 library is the core of the yakIcons system.  Mr.
  17.     Gouthas has been invaluable in the development of yakIcons, if only
  18.     because his library started the whole thing rolling.
  19. Christopher Christensen-- his post on rec.games.programmer became the
  20.     core routines for yakStick, the joystick module.
  21. Chris Busch -- wrote the original bits of the collision code.
  22. SBF-- the Soundblaster Freedom Project, whose routines form the center of
  23.     the yakSample and yakVoc classes.
  24. Jo E. Carter Putz-- my lovely wife, who showed a great deal of patience
  25.     during the development of yakIcons and will no doubt be called upon
  26.     do do more of the same in the future.
  27. Roslyn-- my dog, a seven-month-old Klee Kai, with whom I should have spent a
  28.     lot more time playing!
  29.  
  30. and, of course, you-- any programmer who takes the time to try and write a
  31. game.
  32.  
  33.  
  34. On with the docs!
  35.  
  36. *
  37.  
  38. Any game, no matter how simple, requires graphics in this day and age.  The
  39. most cerebral and atmospheric games to me are still text adventures-- but
  40. writing one is relatively unrewarding, since the user base is quite small.
  41. Graphics, though, opens up a great can of worms for the amateur programmer.
  42. The most immediate problem the programmer has is this: how to place a known
  43. graphic onto the screen?
  44. --------------------------------------------------------------------------
  45. THE ICON CLASS
  46.  
  47. The icon class is truly the heart of the yakIcons library.  It provides
  48. a fast, easy solution to the "get this graphic onto that screen at those
  49. coordinates" problem.  Here's the header file, and we'll go through it by
  50. parts.
  51.  
  52. #ifndef ICON.H
  53.  
  54. #define ICON.H
  55.  
  56. #include "stddefs.h"
  57. #include "yaklib.h"
  58.  
  59. class icon
  60. {
  61. public:
  62.   enum flagType {normal = 0, fast = 1};
  63.   int width, height;
  64.   flagType flags;
  65.   char * unrolledPic;
  66.   icon() {width = height = byteWidth = 0; flags = normal; unrolledPic = NULL; collisionMap = NULL;};
  67.   ~icon() {delete unrolledPic; delete collisionMap;};
  68.   inline byte getPixel(int x, int y);
  69.   void save(char * filename);
  70.   char * useData(unsigned char * myPointer, flagType iflags = normal);
  71.   char * load(char * filename, flagType iflags = normal, yakLib * myYakLib = NULL);
  72.   inline void show(int x, int y, word offset);
  73.   inline void hide(int x, int y, word to_offset, word from_offset);
  74.   inline void showMasked(int x, int y, word offset);
  75.  
  76. //collision system code parts inserted here.  All icons will have collision
  77. //maps.
  78.  
  79.   byte * collisionMap; //contains collision points
  80.   int byteWidth; //width in bytes.
  81.   int setWPacked(int, int); //allocates space for array
  82.   int setCollisionBit(int ix, int iy, booleanFlags flag = on);
  83.   int getCollisionBit(int ix, int iy);
  84.   void spewCollisionTable(void);
  85.   int makeCollisionMap(void);
  86.   int hitXY(int myX, int myY, icon* target, int targetX, int targetY);
  87. // icon zooming code parts inserted here.  Only one zoomtable will exist for
  88. // all icons.
  89.  
  90.   static byte ** zoomTable;
  91.   static int zoomTableWidth;
  92.   static byte ** setZoomTable(int newWidth);
  93.   static void spewZoomTable(void);
  94.   icon * zoomedIcon(int newWidth);
  95.   void showZoomed(int x, int y, word offset, int newWidth);
  96. };
  97.  
  98. char * unRollBlt(char * rolledBlt, int &iwidth, int &iheight);
  99. char * rollBlt(char * unRolledBlt, int &iwidth, int &iheight);
  100.  
  101. #endif
  102.  
  103. Now by parts:
  104.   enum flagType {normal = 0, fast = 1};
  105. This is a type which is enumerated for accuracy (rather than #DEFINEing the
  106. values).  Normal is a normal bitmap; fast is a compiled bitmap (up to four
  107. times faster).
  108.  
  109.   int width, height;
  110. width and height of the image, in pixels.
  111.  
  112.   flagType flags;
  113. the variable used to hold the flagtype above.
  114.  
  115.   char * unrolledPic;
  116. the actual image data is stored here.  See formats.doc.
  117.  
  118.   icon() {width = height = 0; flags = normal; unrolledPic = NULL;};
  119. default constructor.
  120.  
  121.   ~icon() {delete unrolledPic; delete collisionMap;};
  122. default destructor (frees up memory used by the bitmap and collision map).
  123.  
  124.   byte getPixel(int x, int y);
  125. returns the color of a given pixel in the bitmap.  Used in gadgets.cpp, and
  126. I'm sure has other uses as well!  Sorry, no putPixel yet (didn't see the need)
  127.  
  128.   void save(char * filename);
  129. saves an icon to disk under the given filename.  This should end in .yak
  130. for compatibility with animicon, etc.
  131.  
  132.   char * useData(unsigned char * myPointer, flagType iflags = normal);
  133. uses data in a header file as definition data for an icon.  Make a header
  134. file out of an icon with bin2hdr, then use the pointer as an argument for
  135. useData.
  136.  
  137.   char * load(char * filename, flagType iflags = normal, yakLib * myYakLib = NULL);
  138. loads an icon from disk.  Flags can be set to determine if the icon is fast
  139. or normal.  Fast icons can't be saved correctly or getPixel'd!  myYakLib is
  140. the address of a yakLib to load from.
  141.  
  142.   inline void show(int x, int y, word offset);
  143. puts the bitmap to screen, including color zero.  Compiled bitmaps are auto-
  144. matically masked.
  145.  
  146.   inline void hide(int x, int y, word to_offset, word from_offset);
  147. copies a square from from_offset to to_offset, "hiding" the icon's position.
  148.  
  149.   inline void showMasked(int x, int y, word offset);
  150. puts the bitmap to screen, excluding color zero (which is transparent).
  151.  
  152.   byte * collisionMap; //contains collision points
  153. contains the one-bit-per-pixel collision map for the icon.
  154.  
  155.   int byteWidth; //width in bytes.
  156.  
  157.   int setWPacked(int, int); //allocates space for array
  158. sets up the collision map.
  159.  
  160.   int setCollisionBit(int ix, int iy, booleanFlags flag = on);
  161. sets a bit in the collision map.
  162.  
  163.   int getCollisionBit(int ix, int iy);
  164. returns the value of a bit in the collision map.
  165.  
  166.   void spewCollisionTable(void);
  167. "spews" the collision map of an icon to the current output device.  Used
  168. for debugging only.
  169.  
  170.   int makeCollisionMap(void);
  171. References the bitmap of an icon and creates a collision map from it.
  172.  
  173.   int hitXY(int myX, int myY, icon* target, int targetX, int targetY);
  174. Checks to see if the object collided with the icon "target".
  175.  
  176.   static byte ** zoomTable;
  177. The zoomTable contains data for zooming icons.  If a pixel is to be drawn
  178. at a new size, the zoomTable will contain a "1"; if not, a "0".
  179.  
  180.   static int zoomTableWidth;
  181. The width of the zoomTable.
  182.  
  183.   static byte ** setZoomTable(int newWidth);
  184. Creates the indices for the zoom table based on the width of zoomable icons.
  185.  
  186.   static void spewZoomTable(void);
  187. Spews the zoom table to the output device.  Used for debugging.
  188.  
  189.   icon * zoomedIcon(int newWidth);
  190. Allocates space for and returns a new icon, zoomed to the new width
  191. "newWidth".
  192.  
  193.   void showZoomed(int x, int y, word offset, int newWidth);
  194. Shows an icon at a position, zoomed to a new width.
  195.  
  196. char * unRollBlt(char * rolledBlt, int &iwidth, int &iheight);
  197. char * rollBlt(char * unRolledBlt, int &iwidth, int &iheight);
  198.      these two functions aren't part of the icon class, but they do make
  199. things a little easier when converting from a linear to a planar bitmap
  200. (unRollBlt) or a planar to linear (rollBlt).  If the linear bitmap isn't
  201. a multiple of 4 wide, unRollBlt pads it with zeros.  Look at these functions
  202. before you use them; they're a little confusing to me still.
  203.  
  204.  
  205. Got all that?  The basic ideas are pretty straightforward.  Look at the
  206. example programs, particularly view.cpp and vitals.cpp.
  207.  
  208.  
  209. Once the programmer can put objects onto the screen, the next big step is
  210. animation.  This could be a hassle-- the programmer would have to store a
  211. table of shapes in memory, figure out which one to draw at a given time,
  212. and put it there.  Or, they could just use a handy animicon!
  213.  
  214. ------------------------------------------------------------------------
  215. THE ANIMICON CLASS
  216.  
  217. The animicon is simply a linked list of icons.  With each draw, it auto-
  218. matically advances itself to the next frame; the programmer needs to do
  219. nothing.
  220.  
  221. #ifndef ANIMICON.H
  222.  
  223. #define ANIMICON.H
  224.  
  225. #include <stddef.h>
  226. #include "stddefs.h"
  227. #include "icon.h"
  228.  
  229. class animiconNode
  230. {
  231. public:
  232.   animiconNode * nextFrame;
  233.   animiconNode * prevFrame;
  234.   icon picture;
  235.   animiconNode() {nextFrame = NULL; prevFrame = NULL;}
  236.   animiconNode(byte * iconData, animiconNode * nextIcon)
  237.     {picture.useData(iconData); nextFrame = nextIcon; prevFrame = NULL;};
  238. };
  239.  
  240. class animicon
  241. {
  242. public:
  243.   animiconNode * firstFrame;
  244.   animiconNode * lastFrame;
  245.   animiconNode * thisFrame;
  246.   byte numberOfFrames;
  247.   animicon() {firstFrame = lastFrame = thisFrame = NULL; numberOfFrames = 0;}
  248.   animicon(char * filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL);
  249.   ~animicon();
  250.   char far * add(animiconNode * thisNode);
  251.   char far * add(char far *filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL);
  252.   inline void show(int x, int y, word pagebase);//virt
  253.   inline void draw(int x, int y, word pagebase);//virt
  254.   inline void showZoomed(int x, int y, word offset, int newWidth);
  255.   inline void drawZoomed(int x, int y, word offset, int newWidth);
  256.   inline void advance(void); //virt
  257.   void removeTail(void);
  258.   void addAll(char * filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL);
  259.   void hide(int x, int y, word toOffset, word fromOffset);
  260. };
  261.  
  262.  
  263. class animslave
  264. {
  265. public:
  266.   animiconNode * thisFrame;
  267.   animslave() {thisFrame = NULL;}
  268.   virtual void advance(void);
  269.   virtual void advance(int numFrames);
  270.   inline void draw(int x, int y, word pagebase);//virt
  271.   inline void show(int x, int y, word pagebase);//virt
  272.   inline void showZoomed(int x, int y, word offset, int newWidth);
  273.   inline void drawZoomed(int x, int y, word offset, int newWidth);
  274. };
  275.  
  276. #endif
  277. You probably won't have to make any instances of an animiconNode, so we'll
  278. go straight to animicon.
  279.  
  280. class animicon
  281. {
  282. public:
  283.   animiconNode * firstFrame; //the first frame
  284.   animiconNode * lastFrame;  //the last frame
  285.   animiconNode * thisFrame;  //the frame currently being shown
  286.   byte numberOfFrames;       //number of frames in the series
  287.  
  288.   animicon() {firstFrame = lastFrame = thisFrame = NULL; numberOfFrames = 0;}
  289. basic constructor.
  290.  
  291.   animicon(char * filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL);
  292. This reads just like the icon::load function and does just that-- the only
  293. difference is that it loads all the frames of the animation.
  294.  
  295.   ~animicon();
  296. default destructor; frees up all frames of the animicon.
  297.  
  298.   char far * add(animiconNode * thisNode);
  299. adds an animiconNode as a frame in the animicon.
  300.  
  301.   char far * add(char far *filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL);
  302. adds a .yak file as a frame.
  303.  
  304.   inline void show(int x, int y, word pagebase);//virt
  305.   inline void draw(int x, int y, word pagebase);//virt
  306.   inline void showZoomed(int x, int y, word offset, int newWidth);
  307.   inline void drawZoomed(int x, int y, word offset, int newWidth);
  308.   inline void advance(void); //virt
  309. show shows the icon and advances it a frame.  Draw draws the icon and does
  310. not advance.  Advance advances the icon one frame of animation.  ShowZoomed
  311. and drawZoomed are the same as show and draw, but also rescale the icon.
  312.  
  313.   void removeTail(void);
  314. removes the last frame of the animation.
  315.  
  316.   void addAll(char * filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL);
  317. adds all icons in the animation as .yak files.
  318.  
  319.   void hide(int x, int y, word toOffset, word fromOffset);
  320. see the icon implementation.
  321. };
  322.  
  323.  
  324. As you might imagine, animicons are memory hogs, particularly if theyr'e
  325. fast (compiled) icons.  A nice solution to this problem if you have
  326. many instances of a certain icon is the animslave class, which basically
  327. points to an animicon:
  328.  
  329. -------------------------------------------------------------------------
  330. THE ANIMSLAVE CLASS
  331.  
  332.  
  333. class animslave
  334. {
  335. public:
  336.   animiconNode * thisFrame;             //the frame currently pointed to
  337.   animslave() {thisFrame = NULL;}       //the default constructor
  338.  
  339.   virtual void advance(void);
  340. advances the animslave one frame along the animicon
  341.  
  342.   virtual void advance(int numFrames);
  343. advances the animslave a given number of frames.  Advancing an animslave
  344. a random number of frames is a good way to get several similar objects out
  345. of sync.  Note that advancing an animslave does not affect other slaves of
  346. the same animicon, nor does it affect the animicon itself!
  347.  
  348.   inline void draw(int x, int y, word pagebase);//virt
  349.   inline void show(int x, int y, word pagebase);//virt
  350.   inline void showZoomed(int x, int y, word offset, int newWidth);
  351.   inline void drawZoomed(int x, int y, word offset, int newWidth);
  352. you know this by now, I'm sure.
  353. };
  354.  
  355. Obviously a good way to utilize these classes is to take a table of animicons
  356. and make several instances of animslaves to point to them.  You could
  357. cover a screen this way with minimal memory usage!  And that's just what
  358. we'll do.  No game is complete without a good background, and tiled back-
  359. grounds of the ultima/wargame/nintendo style can be nice and effective.
  360.  
  361. --------------------------------------------------------------------------
  362. THE ANIMAP CLASS
  363.  
  364. The animated map is a staple of the wargamer or adventure maker.  We'll
  365. make ours out of an array of map squares that know how to draw themselves:
  366. #ifndef ANIMAP.H
  367.  
  368. #define ANIMAP.H
  369.  
  370. #include "stddefs.h"
  371. #include "animicon.h"
  372.  
  373. class animactor;
  374.  
  375. class animapSquare : public animslave
  376. {
  377.   public:
  378.   byte myIconNumber, myTerrainType;
  379.   int refresh; //should we refresh this square??
  380.   animactor * nextActor;
  381.   animapSquare() : animslave() {thisFrame = NULL; nextActor = NULL; myIconNumber = myTerrainType = 0;};
  382.   inline void display(int x, int y, word pageBase, int squareWidth);
  383.   virtual void advance(void);
  384.   void drawActors(int x, int y, word pageBase);
  385. };
  386.  
  387. typedef char fileNameString[15];
  388.  
  389. class animap
  390. {
  391.   public:
  392.   byte squareWidth;
  393.   word width, height;
  394.   word numIcons;
  395.   int lastScreenX, lastScreenY; //last pixel at which plotting started
  396.   int lastMapX, lastMapY; //last map square at which plotting started
  397.   int lastDrawWidth, lastDrawHeight; //width and height of last draw
  398.   animapSquare * * mapData;
  399.   animicon * iconTable;
  400.   fileNameString * iconNames;
  401.   animap(int numicons, int squidth, int iwidth, int iheight);
  402.   animap(char * filename, yakLib * myYakLib = NULL); //loads and constructs map!
  403.   ~animap();
  404.   void * isInSquare(int x, int y, byte identity);
  405.   void draw(int centerx, int centery, int screenx, int screeny, int radx,int rady, word offset);
  406.   void show(int centerx, int centery, int screenx, int screeny, int radx,int rady, word offset);
  407.   void drawXY(int left, int top, int screenLeft, int screenTop, int width,int height, word offset);
  408.   void showXY(int left, int top, int screenLeft, int screenTop, int width,int height, word offset);
  409.   void smartRefresh(int deltaX, int deltaY, word offset);
  410.   void advance(void);
  411.   void loadIcon(int position, char * filename, yakLib * myYakLib = NULL);
  412.   void save(char * filename);
  413.   void load(char * filename);
  414.   void setSquare(word x, word y, byte icon_number);
  415.   void reset(void);
  416.   void randomize(void);
  417. };
  418.  
  419. #endif
  420.  
  421. class animapSquare : public animslave
  422. {
  423.   public:
  424.   byte myIconNumber, myTerrainType;
  425. These are numbers meant for categorizing terrain.  The icon number is the
  426. number of the icon that will be drawn when this square is shown.  The
  427. terrain type is the type of terrain it really is (ie if you wanted to have
  428. an invisible path through a swamp, set the icon to "swamp" and the terrain
  429. type to "road".
  430.  
  431.   int refresh; //should we refresh this square??
  432. used by smartRefresh();
  433.  
  434.   animactor * nextActor; //a pointer to the first actor on the square
  435.  
  436.   animapSquare() : animslave() {thisFrame = NULL; nextActor = NULL; myIconNumber = myTerrainType = 0;};
  437. default constructor.
  438.  
  439.   inline void display(int x, int y, word pageBase, int squareWidth);
  440. draws the map square and all the actors on it.
  441.  
  442.   virtual void advance(void);
  443. advances the map square one frame and all its actors one frame and one
  444. script line.
  445.  
  446.   void drawActors(int x, int y, word pageBase);
  447. draws the actors on a map.  For a laugh, call this without calling draw()
  448. or display(); the actors will appear without any landscape around them.
  449. Darkness maybe?
  450. };
  451.  
  452. These squares are organized with the larger class, animap:
  453.  
  454. class animap
  455. {
  456.   public:
  457.   byte squareWidth;  //width of a map square in pixels
  458.   word width, height;  //width and height of the map, in squares
  459.   word numIcons;       //number of icons in the map
  460.   int lastScreenX, lastScreenY; //last pixel at which plotting started
  461.   int lastMapX, lastMapY; //last map square at which plotting started
  462.   int lastDrawWidth, lastDrawHeight; //width and height of last draw
  463.   animapSquare * * mapData; //ah, the actual map data!
  464.   animicon * iconTable;     //table of animicons.  Sound familiar?
  465.   fileNameString * iconNames; //names of the icons, for loading/saving.
  466.  
  467.   animap(int numicons, int squidth, int iwidth, int iheight);
  468. Okay, there's no default constructor for the animap.  This will take the
  469. arguments and dynamically allocate memory for a map of the given speci-
  470. fications.  No icons are loaded-- the map is NOT ready for use.
  471.  
  472.   animap(char * filename, yakLib * myYakLib = NULL); //loads and constructs map!
  473. This loads a map from a .map file on disk.  If myYakLib is given, then
  474. the map's icons are loaded from the given yakLib.  The .map file is NOT
  475. loaded from the yakLib! (didn't have time).
  476.  
  477.   ~animap();
  478. default destructor.  Frees up map data and icon data.
  479.  
  480.   void * isInSquare(int x, int y, byte identity);
  481. Queries a square to see if there is an actor with the given identity within.
  482.  
  483.   void draw(int centerx, int centery, int screenx, int screeny, int radx,int rady, word offset);
  484. draws the map, using the square centerx, centery as the center (!), screenx
  485. and screeny for the center on the screen, radx and rady as the x and y
  486. radii (radx=1, rady = 1 shows nine squares), and offset as the screen
  487. offset to write to.  Does not advance icons or actors.
  488.  
  489.   void show(int centerx, int centery, int screenx, int screeny, int radx,int rady, word offset);
  490. Same as above, but advances icons and actors.
  491.  
  492.   void drawXY(int left, int top, int screenLeft, int screenTop, int width,int height, word offset);
  493.   void showXY(int left, int top, int screenLeft, int screenTop, int width,int height, word offset);
  494. same as above, but works on top, left, and width instead of centerx, centery,
  495. and radius.
  496.  
  497.   void smartRefresh(int deltaX, int deltaY, word offset);
  498. redraws the area of screen last drawn on, refreshing only those tiles that
  499. require it.  Actors and map squares larger than squareWidth may not be drawn
  500. correctly.  Very fast.
  501.  
  502.   void advance(void);
  503. advances icons and actors without drawing them.
  504.  
  505.   void loadIcon(int position, char * filename, yakLib * myYakLib = NULL);
  506. loads a yakIcon into a given position in the icon table.
  507.  
  508.   void save(char * filename);
  509. saves the map under the given filename.
  510.  
  511.   void load(char * filename);
  512. loads the map from the given filename.
  513.  
  514.   void setSquare(word x, word y, byte icon_number);
  515. sets a square to a given icon number.  TerrainType = icon number!
  516.  
  517.   void reset(void);
  518. Hmm; I can't remember what this does.  Ah!  This resets every square's icon
  519. to that square's icon number.  Useful if icon pointers get hosed.
  520.  
  521.   void randomize(void);
  522. Randomizes every square on the map.  Can be dangerous if all icons aren't
  523. loaded in!  I used it for debugging purposes; I doubt it could really be
  524. useful in a game.
  525.  
  526. };
  527.  
  528.  
  529. Okay, we're almost ready for the fun part.  If the animap is the stage,
  530. the actor class is naturally next.  But before I tell you that story, I
  531. have to tell you this one: actors work from a script, and before you
  532. go for actors, take a peek at...
  533.  
  534. ------------------------------------------------------------------------
  535. THE SCRIPT CLASS
  536.  
  537. #ifndef SCRIPT.H
  538.  
  539. #define SCRIPT.H
  540.  
  541. #include <stddef.h>
  542. #include "stddefs.h"
  543.  
  544. class scriptNode
  545. {
  546. public:
  547.   enum scriptCommand {doNothing, fineMoveRel, fineSlide, turn};
  548.   scriptNode * nextLine; // what it should do next.
  549.   byte command;
  550.   int mapX, mapY;
  551.   int squareX, squareY;
  552.   scriptNode() {nextLine = NULL; command = mapX = mapY = squareX = squareY = 0;};
  553.   scriptNode(byte icommand, int ix, int iy, int isquareX, int isquareY);
  554. };
  555.  
  556. class script
  557. {
  558. public:
  559.   scriptNode * firstLine, * lastLine, * thisLine;
  560.   script() {firstLine = thisLine = lastLine = NULL;}
  561.   void addLine(byte command, int mapX, int mapY, int squareX, int squareY);
  562.   void addCommand(scriptNode::scriptCommand command, int mapX, int mapY, int squareX, int squareY);
  563.   void advanceLine(void);
  564. };
  565. #endif
  566.  
  567.  
  568. A scriptNode is like a line in a script.  It tells the actor what to do
  569. NOW.
  570.  
  571. class scriptNode
  572. {
  573. public:
  574.  
  575.   enum scriptCommand {doNothing, fineMoveRel, fineSlide, turn};
  576. These are the four commands currently available:
  577.       doNothing: does nothing.
  578.       fineMoveRel: moves the actor (squareX, squareY) pixels
  579.       fineSlide: moves the actor (squareX, squareY) pixels in (mapX) turns
  580.       turn: turns a facing-actor (factor) a given direction (mapX)
  581.  
  582.   scriptNode * nextLine; // what it should do next.
  583.  
  584.   byte command;
  585. the command in this line of script
  586.  
  587.   int mapX, mapY;
  588. two numbers used in the line
  589.  
  590.   int squareX, squareY;
  591. two more numbers used in the line (see scriptCommand above)
  592.  
  593.   scriptNode() {nextLine = NULL; command = mapX = mapY = squareX = squareY = 0;};
  594. default constructor
  595.  
  596.   scriptNode(byte icommand, int ix, int iy, int isquareX, int isquareY);
  597. constructor which sets all the appropriate variables.
  598. };
  599.  
  600.  
  601. Like an animicon is made up of animiconNodes, a script is made up of
  602. scriptNodes:
  603.  
  604. class script
  605. {
  606. public:
  607.   scriptNode * firstLine, * lastLine, * thisLine;  //look familiar?
  608.  
  609.   script() {firstLine = thisLine = lastLine = NULL;}
  610. default constructor
  611.  
  612.   void addLine(byte command, int mapX, int mapY, int squareX, int squareY);
  613. adds a new scriptNode to the script.  Does no parsing.
  614.  
  615.   void addCommand(scriptNode::scriptCommand command, int mapX, int mapY, int squareX, int squareY);
  616. adds several scriptNodes to the script, depending on the command.  Fineslide,
  617. for example, adds several fineMoveRels
  618.  
  619.   void advanceLine(void);
  620. advances one line in the script, deleting the line just executed and freeing
  621. its memory for future use.
  622. };
  623. --------------------------------------------------------------------------
  624. THE ACTOR CLASS
  625.  
  626.  
  627. #ifndef ACTOR.H
  628.  
  629. #define ACTOR.H
  630.  
  631. #include "animicon.h"
  632. #include "animap.h"
  633. #include "script.h"
  634.  
  635. #define MAX_ICONS 20
  636.  
  637. class event;
  638.  
  639. class animactor : public animslave, public script
  640. {
  641. public:
  642.   byte myIconNumber;  // what do we look like?
  643.   byte myIdentity;    // ...and what ARE we?
  644.   word mapX, mapY; //position on parent map
  645.   int lastMapX, lastMapY;
  646.   byte squareX, squareY; //position on map square, so we can move finely
  647.   animactor * nextActor;
  648.   animactor * spawningActor;
  649.   animactor * spawnedActor;
  650.   animap * mymap;
  651.   static animicon * actorIcons;
  652.   animactor() : animslave() {nextActor = spawnedActor = spawningActor = NULL; mymap = NULL; mapX = mapY = squareX = squareY = myIconNumber = 0;}
  653.   virtual void * isInSquare(byte identity);
  654.   void put(int x, int y);
  655.   void remove(void);
  656.   void fineMoveRel(int x, int y);
  657.   void moveTo(int x, int y);
  658.   int hit(animactor * target);
  659.   virtual void advance();
  660.   virtual void show(int x, int y, word pagebase);
  661.   virtual void draw(int x, int y, word pagebase);
  662.   virtual void spawn(animactor * spawnactor);
  663.   virtual void assignIcon(byte iconNumber, byte identity = 255);
  664.   virtual void turn(byte idirection) {};
  665.   static void loadActor(int position, char far * filename, yakLib * myYakLib = NULL);
  666. };
  667.  
  668. #endif
  669. class animactor : public animslave, public script
  670. {
  671. public:
  672.   byte myIconNumber;  // what do we look like?
  673.   byte myIdentity;    // ...and what ARE we?
  674. analagous to the similar numbers in the animap class
  675.  
  676.   word mapX, mapY; //position on parent map
  677.   byte squareX, squareY; //position on map square, so we can move finely
  678. squarex and squarey are pixel placements.  This lets us get away with the
  679. illusion that we're not really on a grid!
  680.  
  681.   animactor * nextActor;
  682. points to the next actor on the square.  Actors are inserted into the list
  683. in z-order so that they "stack" correctly (ie actor "A", behind actor "B",
  684. doesn't overwrite it)
  685.  
  686.   animactor * spawningActor;
  687.   animactor * spawnedActor;
  688. A little more confusing, spawning allows you to temporarily reassign an actor
  689. to a different graphic.  Useful for changing actions of an actor (a regular
  690. actor might be a tank rolling along, which could "spawn" into a firing tank
  691. during combat, for example.)  Particularly useful with events.
  692.  
  693.   animap * mymap;
  694. pointer to the map the actor is on.
  695.  
  696.   static animicon * actorIcons;
  697. A table of animicons the actors use to slave off of.  Filled using loadActor
  698.  
  699.   animactor() : animslave() {nextActor = spawnedActor = spawningActor = NULL; mymap = NULL; mapX = mapY = squareX = squareY = myIconNumber = 0;}
  700. default constructor
  701.  
  702.   virtual void * isInSquare(byte identity);
  703. checks to see if there is an actor with identity (identity) in the same square
  704. as this actor.  Very useful!
  705.  
  706.   void put(int x, int y);
  707. Puts actor on the map.  Be careful you don't put more than one copy!
  708.  
  709.   void remove(void);
  710. Pulls actor off the map.
  711.  
  712.   void fineMoveRel(int x, int y);
  713. Moves actor (x, y) pixels, updating mapx, mapy, squarex, squarey as appropriate
  714.  
  715.   void moveTo(int x, int y);
  716. Moves actor to map square (x, y).
  717.  
  718.   int hit(animactor * target);
  719. Looks to see if this actor hit the target actor.
  720.  
  721.   virtual void advance();
  722. advances actor one frame of animation and one line of script.
  723.  
  724.   virtual void show(int x, int y, word pagebase);
  725. Shows actor and updates a frame/script line.
  726.  
  727.   virtual void draw(int x, int y, word pagebase);
  728. draws actor; does not advance.
  729.  
  730.   virtual void spawn(animactor * spawnactor);
  731. changes graphic to that of the spawnactor.
  732.  
  733.   virtual void assignIcon(byte iconNumber, byte identity = 255);
  734. Assigns icon to an entry in the icon table.
  735.  
  736.   virtual void turn(byte idirection) {};
  737. Put here to make factor.cpp work right.  Does nothing to actors.
  738.  
  739.   static void loadActor(int position, char far * filename, yakLib * myYakLib = NULL);
  740. loads an icon into the position (position) in the actorIcons table.
  741. };
  742.  
  743.  
  744. Associated with Actors are Events, neat little pseudo-actors with a special
  745. property.  Ordinarily, when something like an explosion happens, the user
  746. must keep track of where it is, what frame it's on, etc, putting it on the
  747. map and taking it off when done.  Events are "fire-and-forget" animations
  748. that allocate their own living space, run their animation, and deallocate their
  749. space when the animation is complete.  Use for explosions, spell effects,
  750. missiles, whatever!
  751. --------------------------------------------------------------------------
  752. THE EVENT CLASS
  753.  
  754. #ifndef EVENT.H
  755.  
  756. #define EVENT.H
  757.  
  758. #include "actor.h"
  759.  
  760. #define MAX_EVENTS 10
  761.  
  762. class event : public animactor
  763. {
  764. public:
  765.   void advance(void);
  766.   void addAt(int x, int y, int sqx, int sqy);
  767.   static animicon * eventIcons;
  768.   void assignEvent(byte icon_number, byte identity = 255);
  769.   static void loadEvent(int position, char far * filename, yakLib * myYakLib = NULL);
  770. };
  771. #endif
  772. {
  773.   void advance(void);
  774. Advances a frame of animation and a line of script.  If the end of the animation
  775. has been reached, removes the event and cleans up after itself.  If the event
  776. was spawned (belongs to another actor), the event returns control to the
  777. parent actor when animation is over.
  778.  
  779.   void addAt(int x, int y, int sqx, int sqy);
  780. adds a new copy of the event at the coordinates given to the event's *myMap.
  781.  
  782.   static animicon * eventIcons;
  783. like actorIcons
  784.  
  785.   void assignEvent(byte icon_number, byte identity = 255);
  786. like assignActor
  787.  
  788.   static void loadEvent(int position, char far * filename, yakLib * myYakLib = NULL);
  789. like loadActor
  790. }
  791.  
  792.  
  793. Of course, actors that stay in the same position--even if moving-- aren't
  794. interesting.  If something is traveling left, it should face left; a facing-
  795. actor class is needed.  I have just the thing: the factor (facing-actor) class!
  796. -------------------------------------------------------------------------
  797. THE FACTOR CLASS
  798.  
  799. #ifndef FACTOR.H
  800.  
  801. #define FACTOR.H
  802.  
  803. #include "actor.h"
  804.  
  805.  
  806. #define MAX_FACTORS 10
  807.  
  808. typedef animicon directionTable[10];
  809.  
  810. class factor : public animactor //facing-actor
  811. {
  812. public:
  813.   enum direction {special, southwest, south, southeast, west, center, east,
  814.           northwest, north, northeast};
  815.   enum type {eightFace, twoFace, oneFace, fourFace};
  816.   animiconNode * directionIcons[10];
  817.   byte direction;
  818.   factor() {direction = 5;};
  819.   virtual void advance();
  820.   void turn(byte idirection);
  821.   virtual void spawn(animactor * spawnactor);
  822.   void assignIcon(int icon_number, type mode, char identity = 255);
  823.   static directionTable * ficonTable;
  824.   static void loadFactor(int position, char * special, char * sw, char * s,
  825.             char * se, char * w, char * center, char * e,
  826.             char * nw, char * n, char * ne, yakLib * myYakLib = NULL,
  827.             icon::flagType flags = icon::normal);
  828.   static void clearFactor(int position);
  829. };
  830.  
  831. #endif
  832.  
  833. {
  834. public:
  835.   enum direction {special, southwest, south, southeast, west, center, east,
  836.           northwest, north, northeast};
  837. The enumerated type containing numbers for all the directions.  These cor-
  838. respond to the numbers on your numeric keypad, with zero being "special".
  839.  
  840.   enum type {eightFace, twoFace, oneFace, fourFace};
  841. This is the enumerated type declaring how the icon will be drawn:
  842.     eightFace: different facing for all directions
  843.     twoFace  : all west-facing directions and one n-s direction are the same
  844.            icon; all east-facing directions and the other n-s are also
  845.            one icon
  846.     fourFace : all diagonal directions show the icon for that e-w direction.
  847.     oneFace  : why use this?  It's just like an actor!
  848.  
  849.   animiconNode * directionIcons[10];
  850. The table of icon nodes used for the different directions.  Each points to
  851. a different animicon.
  852.  
  853.   byte direction;
  854. Current direction of the factor
  855.  
  856.   factor() {direction = 5;};
  857. default constructor.  This probably should be a little more robust.
  858.  
  859.   virtual void advance();
  860. like actor::advance.
  861.  
  862.   void turn(byte idirection);
  863. turns the character to the specified direction.  This should probably require
  864. an enumerated direction type.
  865.  
  866.   virtual void spawn(animactor * spawnactor);
  867. like actor::spawn.  Notice that this takes an animactor pointer as an argument,
  868. so factors can spawn actors and vice versa.  Remember the turn() stub function
  869. back in actor.h?  This is why.
  870.  
  871.   void assignIcon(int icon_number, int mode, char identity = 255);
  872. Like assignActor, etc.  This points the whole table to an entry in the ficontable
  873.  
  874.   static directionTable * ficonTable;
  875. Directiontable is an array of animicons; ficonTable is an array of these!
  876.  
  877.   static void loadFactor(int position, char * special, char * sw, char * s,
  878.             char * se, char * w, char * center, char * e,
  879.             char * nw, char * n, char * ne, yakLib * myYakLib = NULL,
  880.             icon::flagType flags = icon::normal);
  881. Looks complex, but this really is just a factor'ed version of the loadActor,
  882. etc functions.  Give it a filename for each of the directions, and it loads in
  883. all frames of the animation in question.
  884.  
  885.   static void clearFactor(int position);
  886. frees up memory occupied by the icons in ficonTable[position].
  887. };
  888.  
  889. And of course, to keep things round, the fevent class, for facing-missiles
  890. or what have you.
  891. --------------------------------------------------------------------------
  892. THE FEVENT CLASS
  893.  
  894.  
  895. #ifndef FEVENT.H
  896.  
  897. #define FEVENT.H
  898.  
  899. #include "factor.h"
  900.  
  901. #define MAX_FEVENTS 10
  902.  
  903. class fevent : public factor
  904. {
  905. public:
  906.   void advance(void);
  907.   void addAt(int x, int y, int sqx, int sqy);
  908.   void assignFevent(int icon_number, int mode, byte identity = 255);
  909.   static directionTable * feventTable;
  910.   static void loadFevent(int position, char * special, char * sw, char * s,
  911.             char * se, char * w, char * center, char * e,
  912.             char * nw, char * n, char * ne, yakLib * myYakLib = NULL,
  913.             icon::flagType flags = icon::normal);
  914. };
  915. #endif
  916. {
  917. public:
  918.   void advance(void);
  919. See event::advance
  920.  
  921.   void addAt(int x, int y, int sqx, int sqy);
  922. see event
  923.  
  924.   void assignFevent(int icon_number, int mode, byte identity = 255);
  925. see assignFactor
  926.  
  927.   static directionTable * fevent_table;
  928. see factorTable.
  929.  
  930.   static void loadFevent(int position, char * special, char * sw, char * s,
  931.             char * se, char * w, char * center, char * e,
  932.             char * nw, char * n, char * ne, yakLib * myYakLib = NULL,
  933.             icon::flagType flags = icon::normal);
  934. see loadFactor
  935. };
  936.  
  937.  
  938. Okay!  This is the basic class infrastructure for yakIcons.  The rest of
  939. the modules are just icing on the cake, but what icing!  Documentation for
  940. the support modules of yakIcons is in yicons2.doc.
  941.